package guru.springframework.services;

import guru.springframework.domain.Modulebase;
import guru.springframework.repositories.ModuleBaseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.sqlite.SQLiteDataSource;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.text.SimpleDateFormat;
/**
 * Created by jt on 1/10/17.
 */
@Service
public class ModuleBaseServiceImpl implements ModuleBaseService {

    private ModuleBaseRepository moduleBaseRepository;
    @Resource
    private MongoTemplate template;

    @Value("${db.moduleUrl}")
    private String dbUrl;

    @Autowired
    private JdbcTemplate jdbcTemplate;


    @Autowired
    public ModuleBaseServiceImpl(ModuleBaseRepository moduleBaseRepository) {
        this.moduleBaseRepository = moduleBaseRepository;

    }


    @Override
    public List<Modulebase> listAll() {
        List<Modulebase> modulebases = new ArrayList<>();
        moduleBaseRepository.findAll().forEach(modulebases::add); //fun with Java 8
        return modulebases;
    }

    @Override
    public Modulebase getById(String id) {
        return moduleBaseRepository.findById(id).orElse(null);
    }

    @Override
    public Modulebase saveOrUpdate(Modulebase modulebase) {
        moduleBaseRepository.save(modulebase);
        return modulebase;
    }

    @Override
    public void delete(String id) {
        moduleBaseRepository.deleteById(id);
    }

    @Override
    public List<Modulebase> getModulebases(int pageNum, int pageSize) {
        Query query = new Query();
        //设置起始数
        query.skip((pageNum - 1) * pageSize);
        //设置查询条数
        query.limit(pageSize);
//        if (conditions != null) {
//            for (String field: conditions.keySet()) {
//                query.addCriteria(new Criteria(field).is(conditions.get(field)));
//            }
//        }
//        System.err.println("bbbbbb"+moduleBaseRepository.count());
        return template.find(query, Modulebase.class, "ModuleBase");
    }

    @Override
    public void saveDataToSqllie() {
        try {
            String dbPath = new File(dbUrl.substring("jdbc:sqlite:".length())).getAbsolutePath();
            System.err.println(dbPath);
            java.nio.file.Files.deleteIfExists(java.nio.file.Paths.get(dbPath));
        SQLiteDataSource dataSource = new SQLiteDataSource();
        dataSource.setUrl(dbUrl); // 指定数据库文件路径
        // 创建JdbcTemplate实例
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        jdbcTemplate.execute("DROP TABLE IF EXISTS ModuleBase");
        // 创建数据库表
        jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS ModuleBase (" +
                "_id TEXT PRIMARY KEY, " +
                "Start INTEGER, " +
                "Description TEXT," +
                "ModuleCode TEXT," +
                "ModuleName TEXT," +
                "ModuleTypeCode TEXT," +
                "PublicModule INTEGER," +
                "ModulePlugFullTypeMain TEXT," +
                "ModulePlugAssemblyFileName TEXT," +
                "ModulePlugVersion TEXT," +
                "Interfaces TEXT," +
                "ModuleMapXML TEXT," +
                "UserName TEXT," +
                "EditDateTime TEXT," +
                "Status INTEGER)");
        System.out.println("Database and table created successfully");
        long moduleTotal=moduleBaseRepository.count();
        final int INSERT_BATCH_DIVISOR = 200;
        int times = (int)moduleTotal / INSERT_BATCH_DIVISOR;
        int remain = (int)moduleTotal % INSERT_BATCH_DIVISOR;
        for (int i = 0; i < times; i++) {
            Query query = new Query();
            //设置起始数
            query.skip((i) * INSERT_BATCH_DIVISOR);
            //设置查询条数
            query.limit(INSERT_BATCH_DIVISOR);
            List<Modulebase> modulebases=template.find(query, Modulebase.class, "ModuleBase");
//            Gson gson=new Gson();
//            System.out.println(gson.toJson(modulebases));
            batchInsert(modulebases);
        }
        if (remain > 0) {
          Query query = new Query();
          query.skip((times) * INSERT_BATCH_DIVISOR);
          query.limit(INSERT_BATCH_DIVISOR);
          List<Modulebase> modulebases=template.find(query, Modulebase.class, "ModuleBase");
//          Gson gson=new Gson();
//          System.out.println(gson.toJson(modulebases));
          batchInsert(modulebases);
        }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public synchronized void  batchInsert(final List<Modulebase> entities) {
        String sql = "INSERT INTO ModuleBase (_id, Start,Description,ModuleCode,ModuleName,ModuleTypeCode,PublicModule,ModulePlugFullTypeMain,ModulePlugAssemblyFileName,ModulePlugVersion,Interfaces,ModuleMapXML,UserName,EditDateTime,Status) VALUES (?, ?,?, ?,?, ?,?, ?,?, ?,?, ?,?, ?,?)";
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int[] updateCounts = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Modulebase entity = entities.get(i);
                ps.setString(1, entity.get_id());
                ps.setInt(2, entity.getStart());
                ps.setString(3, entity.getDescription());
                ps.setString(4, entity.getModuleCode());
                ps.setString(5, entity.getModuleName());
                ps.setString(6, entity.getModuleTypeCode());
                Boolean publicModule=entity.getPublicModule();
                int publicModuleResult = (publicModule ==Boolean.FALSE) ? 0 : 1;
                ps.setInt(7, publicModuleResult);
                ps.setString(8, entity.getModulePlugFullTypeMain());
                ps.setString(9, entity.getModulePlugAssemblyFileName());
                ps.setString(10, entity.getModulePlugVersion());
                ps.setString(11, Arrays.toString(entity.getInterfaces()));
                ps.setString(12, entity.getModuleMapXML());
                ps.setString(13, entity.getUserName());
                ps.setString(14, formatter.format(entity.getEditDateTime()));
                ps.setInt(15, entity.getStatus());
            }

            @Override
            public int getBatchSize() {
                return entities.size();
            }
        });
        // updateCounts contains the count of rows updated for each statement in the batch
    }
}
